/*
*       SYS.H.HRDSTATE
*
*       Definition of hardware devices state structure for DIVA PC
*
*       18-12-91 INH  Original
*       23-01-92      Added suspend / resume functions
*       15-04-92      Device modules: R12 fields added; CFG call chain added
*       13-12-94      A20Gate control added
* 	20-03-95      DMA Request fn's added; Version numbering added
*	10-11-95      v2.00 HPC bits added
*/



/*

Memory and I/O space is divided into chunks; each chunk has a Read8,
Read16, Write8 and Write16 handler function. There are 256 I/O chunks
(4-byte blocks from I/O addresses 0-3 to 3FC-3FF) and 24 memory chunks
(16K portions: the first is A0000-A3FFF and the last FC000-FFFFF;
below A0000 is assumed to be RAM and is the responsibility of the
processor module; ditto any RAM at 1M and over).

*/

  /* Don't alter anything here without consulting SYS.S.SYSS */


struct CallList
{
  union
  {
    EvtFnPtr Evt;
    CfgFnPtr Cfg;
  } fn;

  struct CallList *next;
  int   R12value;
};


struct HardwareState
{
  /* Version numbers */

#define HRDSTATE_CURR_VER 200
 int current_ver;            /* Current version of structure */


#define HRDSTATE_MIN_VER 175
 int min_compat_ver;         /* Minimum version # with which this
                                 structure is compatible. Numbers
                                 are multiplied by 100 decimal e.g.
                                 v1.79 is 179 decimal   */


    /* 24 memory handlers */

#define SYS_nMemSlots  24
#define SYS_MemSpacing 0x4000
#define SYS_MemBase    0xA0000
  Handler Memhandlers [SYS_nMemSlots];

    /* 256 Handlers, one for each 4-byte I/O chunk */

#define SYS_nIOSlots  256
#define SYS_IOSpacing   4
  Handler IOhandlers  [SYS_nIOSlots];

/*
   DMA Handlers:

   Routines provided by devices to emulate DMA transfers.
   Docs for this are available separately (DMASPEC.DOC).
*/

#define SYS_nDMAslots 8
  DMA_handler DMAhandlers[SYS_nDMAslots];

/*

  NullHandlers
     This has pointers to dummy routines in the CPU module
     which are intended for any space where a device is not
     present: for writes they will ignore the data and for
     reads they will return zero. If a device module needs
     to remove itself from a particular memory or I/O chunk,
     it can copy NullHandlers into the slot it has just
     vacated, thus ensuring there is still a valid function
     pointer in the slot.

  NullDMAhandler
     In the same way, this contains addresses of dummy
     routines to safely ignore DMA transfers. Devices wishing
     to no longer perform DMA should copy this structure into
     their DMA slot.

*/

  Handler NullHandlers;

  DMA_handler NullDMAhandler;

/*
     CPU_Interrupt

     This is a pointer to a function in the CPU module which
     a device may use for causing interrupts. It is passed the
     *hardware* interrupt number.

*/

  OneIntFnPtr CPU_Interrupt;
  int         IntsAvailable; /* Bit-mask; Bit 0 is '1' if IRQ0 can be
                                generated by CPU_Interrupt, and so on */

/*
     DMA_Request

     Pointer to a function in the DMA subsection of the CPU module,
      which generates a DMA request on the given channel.

     DMAsAvailable is a bit mask: bit 0 is 1 if DMA channel 0 works,
      bit 1 is DMA channel 1, etc
*/

  OneIntFnPtr DMA_Request;
  int         DMAsAvailable;


/*
    SetA20gate

    Pointer to a function to set the state of the A20gate line.
    SetA20gate(0) disables A20 (i.e. nasty-8086-compatible mode)
    SetA20gate(nonzero) enables it (for protected mode)

    This is only of relevance to the CPU and 8042 keyboard controller
      device.
*/

   OneIntFnPtr SetA20gate; /* SetA20gate(0) disables A20;
                              SetA20gate(nonzero) enables it */

/*
     Event Functions

     'eventlist' defines several 'Call Lists', one per event.
     Each list is a linked list of pointers to functions.
     Each device module which is interested in a particular
     event can add a routine to the relevant list. When a particular
     event occurs, all the functions on the appropriate list
     are called in sequence.

     The events available are:

     HardReset: intended to simulate a hardware reset. This
     should reset all internal "hardware" state in device
     modules.

     Poll_chain: while the CPU is running, Poll_chain will
     happen at regular intervals; during this, the device
     may not use CPUHandlers etc.

     StopFE: whenever the emulation has to be suspended because
     the "front end" is wanted by someone else, the
     'StopFE' event is called. StopFE will also be called before any
     SYS_Shutdown call is made.

     StartFE: when the "front end" is about to be used for emulation
     purposes, either for the first time after all devices have been
     initialised, or after execution has been suspended, a StartFE
     event will be called.

     Numbers for these events are defined in sys.h.sys

     Note that event functions are defined to return a bool. This
     should always be false, or else events further down the chain
     will not be called.
*/

struct CallList  *eventlist [SYS_nEvents];

/*   Config functions list

     This is a list of functions to be called when an unknown line in
     the config file is called.

*/


struct CallList *Config_list;

  /* New bits for v2.00.

     See HPC.DOC for a detailed description of these.
  */

#define ServiceIDHashFn(sid) ((sid) & 15)
#define HPC_HASH_LIST_SIZE 16
  HPC_handler *HPCHandlerLists[HPC_HASH_LIST_SIZE];

  OneIntFnPtr HPC_SetRequest;
};


/* Definition of the SYS_State variable; kept in module space now */

extern struct HardwareState *SYS_State_Ptr;

#define SYS_State (*SYS_State_Ptr)


